package TextNor.AssignTag;import test.Num;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import DecisionTree.AttributeSet;
import DecisionTree.AttributeValue;
import DecisionTree.DecisionTree;
import DecisionTree.IdSymbolicAttribute;
import DecisionTree.Item;
import DecisionTree.ItemSet;
import DecisionTree.KnownNumericalValue;
import DecisionTree.KnownSymbolicValue;
import DecisionTree.UnknownSymbolicValue;
import DecisionTree.io.ItemSetReader;
import DecisionTree.io.ReadWriteDecisionTree;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

/**
 *
 * @author phamthanh
 */
public final class NumTag_AsignCom {

    private ArrayList tokenAr = new ArrayList();
    private ArrayList itemAr = new ArrayList();
    private AttributeSet attributeSet;
    private DecisionTree tree;
    private ItemSet learningSet;

  

//    public static void main(String argv[]) throws XMLStreamException, IOException {
//        NumTag nt = new NumTag();
//
//
//    }

    public NumTag_AsignCom(String inf, String ouf) throws FileNotFoundException, XMLStreamException, IOException, ClassNotFoundException {
        long startTime = System.currentTimeMillis();
        setTokenAr(inf);
        setItemAr();
        createDecisionTree();
        asignNumTag(inf, ouf);
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;

        System.out.println("package TextNor.AssignTag; class NumgTag_AsignCom");
        
        System.out.println("Thoi gian gan the num la: " + time);
    }

    public void createDecisionTree() throws IOException, FileNotFoundException, ClassNotFoundException {
        this.learningSet = null;
        try{
        //learningSet = ItemSetReader.read(new FileReader("data\\dt\\tree.db"));
        learningSet = ItemSetReader.read("data\\tree\\ncomtreedata.db");
        }catch (IOException e){
            e.printStackTrace();
            System.out.println("khong doc duoc file");
        }

        this.attributeSet = learningSet.attributeSet();
//
//        Vector testAttributesVector = new Vector();
//        testAttributesVector.add(attributeSet.findByName("charCount"));
//        testAttributesVector.add(attributeSet.findByName("numCount"));
//        testAttributesVector.add(attributeSet.findByName("chamCount"));
//        testAttributesVector.add(attributeSet.findByName("cheoCount"));
//        testAttributesVector.add(attributeSet.findByName("ngangCount"));
//        testAttributesVector.add(attributeSet.findByName("haiChamCount"));
//        testAttributesVector.add(attributeSet.findByName("tknBf2"));
//        testAttributesVector.add(attributeSet.findByName("tknBf1"));
////        testAttributesVector.add(attributeSet.findByName("nswStr"));
//        testAttributesVector.add(attributeSet.findByName("tknAf1"));
//        testAttributesVector.add(attributeSet.findByName("tknAf2"));
//
//
//        AttributeSet testAttributes = new AttributeSet(testAttributesVector);
//        SymbolicAttribute goalAttribute =
//                (SymbolicAttribute) learningSet.attributeSet().findByName("classNsw");
//
//        this.tree = buildTree(learningSet, testAttributes,
//                goalAttribute);
//        printDot(tree);
                ReadWriteDecisionTree rwd=new ReadWriteDecisionTree();
//        rwd.writeToFile("data//dt//numTree.db", tree);
        tree=rwd.readFromFile("data//tree//ncomtree.db");

    }
// static private void printDot(DecisionTree tree) throws FileNotFoundException, UnsupportedEncodingException, IOException {
//        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("resources\\ncomtree.dot"), "UTF8"));
//	System.out.println((new DecisionTreeToDot(tree)).produce());
//        String dotFile=(new DecisionTreeToDot(tree)).produce();
//        bw.write(dotFile);
//        bw.close();
//    }
//    static private DecisionTree buildTree(ItemSet learningSet,
//            AttributeSet testAttributes,
//            SymbolicAttribute goalAttribute) {
//        DecisionTreeBuilder builder = new DecisionTreeBuilder(learningSet, testAttributes, goalAttribute);
//
//        return builder.build().decisionTree();
//    }

    public String  guessTag(int itemIndex) {
        Num num = (Num) itemAr.get(itemIndex);
        Item item = convertNumToItem(num);
//        Item item=learningSet.item(0);
        KnownSymbolicValue guessedGoalAttributeValue = tree.guessGoalAttribute(item);
        System.out.println(tree.getGoalAttribute().valueToString(guessedGoalAttributeValue));
        
        return tree.getGoalAttribute().valueToString(guessedGoalAttributeValue);
////        return "";
    }

    public Item convertNumToItem(Num num) {
//        AttributeValue[] values = new AttributeValue[8];
//
//        values[1] = new KnownNumericalValue(num.getChaCount());
//        values[2] = new KnownNumericalValue(num.getNumCount());
//        IdSymbolicAttribute attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(3);
//        values[3] = new KnownSymbolicValue(attribute.find(num.gettknBf2()));
//
//        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(4);
//        values[4] = new KnownSymbolicValue(attribute.find(num.gettknBf1()));
//
////        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(5);
////        values[5] = new KnownSymbolicValue(attribute.find(num.getNswStr()));
//
//        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(6);
//        values[6] = new KnownSymbolicValue(attribute.find(num.gettknAf1()));
//
//        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(7);
//        values[7] = new KnownSymbolicValue(attribute.find(num.gettknAf2()));
//        Item item = new Item(values);
//        return item;
        
        
         AttributeValue[] values = new AttributeValue[13];

        values[1] = new KnownNumericalValue(num.getChaCount());
        values[2] = new KnownNumericalValue(num.getNumCount());
        values[3] = new KnownNumericalValue(num.getChamCount());
        values[4] = new KnownNumericalValue(num.getCheoCount());
        values[5] = new KnownNumericalValue(num.getNgangCount());
        values[6] = new KnownNumericalValue(num.getHaiChamCount());
//        IdSymbolicAttribute attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(3);
//        values[3] = new KnownSymbolicValue(attribute.find(num.gettknBf2()));
//
//        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(4);
//        values[4] = new KnownSymbolicValue(attribute.find(num.gettknBf1()));
        
        IdSymbolicAttribute attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(7);
        int index=attribute.find(num.getTknBf2());
        if(index==-1){
            values[7] = new UnknownSymbolicValue();
        }else{
            values[7] = new KnownSymbolicValue(index);
        }
        
        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(8);
        index=attribute.find(num.getTknBf1());
        if(index==-1){
            values[8] = new UnknownSymbolicValue();
        }else{
            values[8] = new KnownSymbolicValue(index);
        }

//        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(5);
//        values[5] = new KnownSymbolicValue(attribute.find(num.getNswStr()));

     
        
        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(10);
        index=attribute.find(num.getTknAf1());
        if(index==-1){
            values[10] = new UnknownSymbolicValue();
        }else{
            values[10] = new KnownSymbolicValue(index);
        }
        
        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(11);
        index=attribute.find(num.getTknAf2());
        if(index==-1){
            values[11] = new UnknownSymbolicValue();
        }else{
            values[11] = new KnownSymbolicValue(index);
        }
//        attribute = (IdSymbolicAttribute) attributeSet.attributes().elementAt(7);
//        values[7] = new KnownSymbolicValue(attribute.find(num.gettknAf2()));
        Item item = new Item(values);
        return item;
    }

    public void setTokenAr(String inf) throws FileNotFoundException, XMLStreamException {
        FileInputStream fis = new FileInputStream(inf);
        XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fis);

        while (xmlStreamReader.hasNext()) {
            int eventCode = xmlStreamReader.next();
            switch (eventCode) {
                case XMLStreamConstants.START_ELEMENT:
                    String localName = xmlStreamReader.getLocalName();
                    if (localName.equals("W")) {
                        String attributeValue = xmlStreamReader.getAttributeValue(0);
                        String nsw = xmlStreamReader.getElementText();
                        Token tkn = new Token();
                        tkn.setValue(nsw);
                        tkn.setNsw(attributeValue);
                        tokenAr.add(tkn);


                    }
                    break;
                case XMLStreamConstants.CHARACTERS:
                    String character = xmlStreamReader.getText();
                    StringTokenizer st = new StringTokenizer(character);
                    while (st.hasMoreTokens()) {

                        String tokenStr = st.nextToken();
                        Token token = new Token();
                        token.setValue(tokenStr);
                        token.setNsw("NOT");
                        tokenAr.add(token);
                    }

            }
        }


       

    }

    public void setItemAr() {

        for (int i = 0; i < this.tokenAr.size(); i++) {
            Token tkn = new Token();
            tkn = (Token) this.tokenAr.get(i);
            if (tkn.getNsw().equals("NUMBER")) {
                Num item = new Num();
                String tknValue = tkn.getValue();
                String tknNsw = tkn.getNsw();
                item.setClassNsw(tknNsw);
                item.setChaCount(tknValue.length());
                item.setNumCount(getNumCount(tknValue));
                item.setChamCount(getChamCount(tknValue));
                item.setCheoCount(getCheoCount(tknValue));
                item.setNgangCount(getNgangCount(tknValue));
                item.setHaiChamCount(getHaiChamCount(tknValue));
                item.setTknAf1(getToken(i + 1));
                item.setTknAf2(getToken(i + 2));
                item.setTknBf1(getToken(i - 1));
                item.setTknBf2(getToken(i - 2));
                item.setNswStr(tknValue);
                itemAr.add(item);
            }

        }
  
    }

    public int getNumCount(String nsw) {
        int count = 0;
        for (int i = 0; i < nsw.length(); i++) {
            if (Character.isDigit(nsw.charAt(i))) {
                count++;
            }
        }
        return count;
    }

    public String getToken(int index) {
        if (index < 0 || index >= this.tokenAr.size()) {
            return "";
        } else {
            Token tkn = (Token) this.tokenAr.get(index);
            return tkn.getValue();
        }

    }

    public boolean isNum(String nsw) {
        for (int i = 0; i < nsw.length(); i++) {
            if (Character.isDigit(nsw.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    public void asignNumTag(String inf, String ouf) throws XMLStreamException, UnsupportedEncodingException, IOException {
FileInputStream fis = new FileInputStream(inf);
        XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(fis);

        FileOutputStream fos = new FileOutputStream(ouf);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
        XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(osw);
        int index=0;
        xmlStreamWriter.writeStartElement("root");
        while (xmlStreamReader.hasNext()) {
            int eventCode = xmlStreamReader.next();
            switch (eventCode) {

                case XMLStreamConstants.START_ELEMENT:
                    String localName = xmlStreamReader.getLocalName();
                    if (localName.equals("record")) {
                        String RecId = xmlStreamReader.getAttributeValue(0);
                        xmlStreamWriter.writeStartElement(localName);
                        xmlStreamWriter.writeAttribute("RecId", RecId);

                    }

                    if (localName.equals("URL")) {
                        String url = xmlStreamReader.getElementText();

                        xmlStreamWriter.writeStartElement(localName);
                        xmlStreamWriter.writeCharacters(url);
                        xmlStreamWriter.writeEndElement();

                    }
                    if (localName.equals("Infomation")) {
                        xmlStreamWriter.writeStartElement(localName);
                    }

                    if (localName.equals("W")) {
                        String attributeName = xmlStreamReader.getAttributeLocalName(0);
                        String attributeValue = xmlStreamReader.getAttributeValue(0);
                        if (!attributeValue.equals("NUMBER")) {
                            String nsw = xmlStreamReader.getElementText();
                            xmlStreamWriter.writeStartElement(localName);
                            xmlStreamWriter.writeAttribute(attributeName, attributeValue);
                            xmlStreamWriter.writeCharacters(nsw);
                            xmlStreamWriter.writeEndElement();

                        } else {
                            String nsw = xmlStreamReader.getElementText();
                            String classNsw = guessTag(index);
                            index++;
                            xmlStreamWriter.writeStartElement(localName);
                            xmlStreamWriter.writeAttribute("NSW", classNsw);
                            xmlStreamWriter.writeCharacters(nsw);
                            xmlStreamWriter.writeEndElement();
                        }
                    }

                    if (localName.equals("SPLIT")) {
                        xmlStreamWriter.writeStartElement(localName);
                    }
                    break;

                case XMLStreamConstants.END_ELEMENT:
                    String endLocalName = xmlStreamReader.getLocalName();

                    if (endLocalName.equals("record")) {
                        xmlStreamWriter.writeEndElement();
                    }
                    if (endLocalName.equals("Infomation")) {
                        xmlStreamWriter.writeEndElement();
                    }

                    if (endLocalName.equals("SPLIT")) {
                        xmlStreamWriter.writeEndElement();
                    }
                    break;
                case XMLStreamConstants.CHARACTERS:
                    String character = xmlStreamReader.getText();
                    xmlStreamWriter.writeCharacters(character);
                    break;

                default:
                    break;
            }
        }

        xmlStreamWriter.writeEndElement();

        xmlStreamReader.close();
        xmlStreamWriter.close();
        fis.close();
        fos.close();

    }
    public int getChamCount(String nsw){
     Pattern p=Pattern.compile("\\.");
     Matcher m=p.matcher(nsw);
     int cham=0;
     while(m.find()){
         cham++;
     }
     return cham;
 }

  public int getNgangCount(String nsw){
     Pattern p=Pattern.compile("\\p{Pd}");
     Matcher m=p.matcher(nsw);
     int ngang=0;
     while(m.find()){
         ngang++;
     }
     return ngang;
 }  
  
    public int getCheoCount(String nsw){
     Pattern p=Pattern.compile("/");
     Matcher m=p.matcher(nsw);
     int cheo=0;
     while(m.find()){
         cheo++;
     }
     return cheo;
 }
    public int getHaiChamCount(String nsw){
     Pattern p=Pattern.compile(":");
     Matcher m=p.matcher(nsw);
     int haiCham=0;
     while(m.find()){
         haiCham++;
     }
     return haiCham;
 }
}
